﻿using System;
using System.Runtime.InteropServices;

namespace Video.Hik
{
    // https://open.hikvision.com/docs/2d4e3a762f4949f8ae85302d1cdee9a1#a390dbc9
    // HCNetSDK.dll可以去海康官方下载
    class CHCNetSDK
    {
        //序列号长度
        public const int SERIALNO_LEN = 48;
        public const int STREAM_ID_LEN = 32;
        public const int INVOKE_FAILURE = -1;
        public const int UNLOGGED = -1;

        /// <summary>
        /// 初始化SDK，调用其他SDK函数的前提。
        /// </summary>
        /// <returns>
        /// TRUE表示成功，FALSE表示失败。接口返回失败请调用NET_DVR_GetLastError获取错误码，通过错误码判断出错原因。
        /// 0: 没有错误
        /// 41：SDK资源分配错误。
        /// 53：获得本地PC的IP地址或物理地址失败。
        /// </returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_Init();

        /// <summary>
        /// 启用写日志文件
        /// </summary>
        /// <param name="bLogEnable">日志的等级（默认为0）：
        /// 0-表示关闭日志，
        /// 1-表示只输出ERROR错误日志，
        /// 2-输出ERROR错误信息和DEBUG调试信息，
        /// 3-输出ERROR错误信息、DEBUG调试信息和INFO普通信息等所有信息</param>
        /// <param name="strLogDir">日志文件的路径，windows默认值为"C:\\SdkLog\\"；linux默认值"/home/sdklog/"</param>
        /// <param name="bAutoDel">是否删除超出的文件数，默认值为TRUE</param>
        /// <returns>TRUE表示成功，FALSE表示失败。</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_SetLogToFile(int bLogEnable, string strLogDir, bool bAutoDel);


        /// <summary>
        /// 返回最后操作的错误码。
        /// </summary>
        /// <returns>https://open.hikvision.com/hardware/definitions/NET_DVR_GetLastError.html</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern uint NET_DVR_GetLastError();


        /// https://open.hikvision.com/hardware/definitions/NET_DVR_Login_V30.html?_blank
        /// <summary>
        /// 用户注册设备。
        /// </summary>
        /// <param name="sDVRIP">设备IP地址或是静态域名，字符数不大于128个</param>
        /// <param name="wDVRPort"> 设备端口号 </param>
        /// <param name="sUserName"> 登录的用户名</param>
        /// <param name="sPassword"> 用户密码</param>
        /// <param name="lpDeviceInfo"> 设备信息</param>
        /// <returns>-1表示失败，其他值表示返回的用户ID值。该用户ID具有唯一性，后续对设备的操作都需要通过此ID实现。接口返回失败请调用NET_DVR_GetLastError获取错误码，通过错误码判断出错原因。</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern int NET_DVR_Login_V30(string sDVRIP, int wDVRPort, string sUserName, string sPassword, ref NET_DVR_DEVICEINFO_V30 lpDeviceInfo);

        /// <summary>
        /// 用户注销。
        /// </summary>
        /// <param name="iUserID"> 用户ID号，NET_DVR_Login_V40等登录接口的返回值</param>
        /// <returns>TRUE表示成功，FALSE表示失败。</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_Logout_V30(int iUserID);


        /// <summary>
        /// 实时预览（支持多码流）。
        /// </summary>
        /// <param name="iUserID">NET_DVR_Login()或NET_DVR_Login_V30()的返回值</param>
        /// <param name="lpPreviewInfo">预览参数</param>
        /// <param name="fRealDataCallBack_V30">码流数据回调函数</param>
        /// <param name="pUser">用户数据</param>
        /// <returns>-1表示失败，其他值作为NET_DVR_StopRealPlay等函数的句柄参数</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern int NET_DVR_RealPlay_V30(int iUserID, ref NET_DVR_PREVIEWINFO lpPreviewInfo, REALDATACALLBACK fRealDataCallBack_V30, IntPtr pUser);

        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern int NET_DVR_RealPlay_V40(int iUserID, ref NET_DVR_PREVIEWINFO lpPreviewInfo, REALDATACALLBACK fRealDataCallBack_V30, IntPtr pUser);

        /// <summary>
        /// 停止预览。
        /// </summary>
        /// <param name="iRealHandle">预览句柄，NET_DVR_RealPlay或者NET_DVR_RealPlay_V30的返回值</param>
        /// <returns>TRUE表示成功，FALSE表示失败。</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_StopRealPlay(int iRealHandle);

        /// <summary>
        /// 获取预览时用来解码和显示的播放器句柄。
        /// </summary>
        /// <param name="lRealHandle">预览句柄，NET_DVR_RealPlay或者NET_DVR_RealPlay_V30的返回值</param>
        /// <returns>－1表示失败，其他值表示播放句柄</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern int NET_DVR_GetRealPlayerIndex(int lRealHandle);

        /// <summary>
        /// 预览时，单帧数据捕获并保存成图片。
        /// </summary>
        /// <param name="lRealHandle">NET_DVR_RealPlay或NET_DVR_RealPlay_V30的返回值</param>
        /// <param name="sPicFileName">保存图象的文件路径（包括文件名）。路径长度和操作系统有关，sdk不做限制，windows默认路径长度小于等于256字节（包括文件名在内）。</param>
        /// <returns>TRUE表示成功，FALSE表示失败。
        /// 0: 没有错误。
        /// 12: 调用次序错误。
        /// 17: 参数错误。SDK接口中给入的输入或输出参数为空。
        /// </returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_CapturePicture(int lRealHandle, string sPicFileName);

        /// https://open.hikvision.com/hardware/definitions/NET_DVR_CaptureJPEGPicture.html?_blank
        /// <summary>
        /// 单帧数据捕获并保存成JPEG图。
        /// </summary>
        /// <param name="lUserID">NET_DVR_Login_V40等登录接口的返回值</param>
        /// <param name="lChannel">通道号</param>
        /// <param name="lpJpegPara">JPEG图像参数</param>
        /// <param name="sPicFileName">保存JPEG图的文件路径（包括文件名）</param>
        /// <returns>TRUE表示成功，FALSE表示失败。</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_CaptureJPEGPicture(int lUserID, int lChannel, ref NET_DVR_JPEGPARA lpJpegPara, string sPicFileName);

        /// <summary>
        /// 主码流动态产生一个关键帧。
        /// </summary>
        /// <param name="lUserID">NET_DVR_Login_V40等登录接口的返回值</param>
        /// <param name="lChannel">通道号</param>
        /// <returns>TRUE表示成功，FALSE表示失败。</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_MakeKeyFrame(int lUserID, int lChannel);

        /// <summary>
        /// 捕获数据并存放到指定的文件中。
        /// </summary>
        /// <param name="lRealHandle"> NET_DVR_RealPlay或NET_DVR_RealPlay_V30的返回值</param>
        /// <param name="sFileName"> 文件路径指针，包括文件名，例如："D:\\test.mp4"</param>
        /// <returns>TRUE表示成功，FALSE表示失败。</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_SaveRealData(int lRealHandle, string sFileName);

        /// <summary>
        /// 停止数据捕获。
        /// </summary>
        /// <param name="lRealHandle"> NET_DVR_RealPlay或NET_DVR_RealPlay_V30的返回值</param>
        /// <returns>TRUE表示成功，FALSE表示失败。</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_StopSaveRealData(int lRealHandle);

        /// <summary>
        /// 释放SDK资源，在结束之前最后调用
        /// </summary>
        /// <returns>TRUE表示成功，FALSE表示失败</returns>
        [DllImport(@".\bin\HCNetSDK.dll")]
        public static extern bool NET_DVR_Cleanup();

    }
}
